package com.ybox.auth.controller;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Email;

import com.ybox.auth.domain.Sms;
import com.ybox.auth.service.LoginService;
import com.ybox.auth.service.SendMessageService;
import com.ybox.common.core.constant.CacheConstants;
import com.ybox.common.core.utils.uuid.IdUtils;
import com.ybox.common.core.web.domain.AjaxResult;
import com.ybox.common.redis.service.RedisService;
import com.ybox.system.api.domain.SysUser;
import com.ybox.system.api.model.LoginUser;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.ybox.auth.form.LoginBody;
import com.ybox.auth.form.RegisterBody;
import com.ybox.common.core.domain.R;
import com.ybox.common.core.utils.JwtUtils;
import com.ybox.common.core.utils.StringUtils;
import com.ybox.common.security.auth.AuthUtil;
import com.ybox.common.security.service.TokenService;
import com.ybox.common.security.utils.SecurityUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * token 控制
 *
 * @author ych
 */
@RestController
public class TokenController {
    @Autowired
    private TokenService tokenService;

    @Autowired
    private LoginService loginService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SendMessageService sendMessageService;

    @PostMapping("login")
    public R<?> login(@Validated({LoginBody.login.class}) @RequestBody LoginBody loginBody) {
        // 用户登录
        LoginUser userInfo = loginService.login(loginBody.getUsername(), loginBody.getPassword());
        // 获取登录token
        return R.ok(tokenService.createToken(userInfo));
    }

    @PostMapping("phone")
    public R<?> loginByPhone(@RequestBody @Validated(RegisterBody.register.class)RegisterBody registerBody) {
        // 1.校验用户名是否存在
        LoginUser loginUser = null;
        loginUser = loginService.loginByPhone(registerBody.getPhone());

        if (null == loginUser){
            // 2.用户注册
            loginService.register(registerBody);

            // 3.注册之后直接登录
            loginUser = loginService.loginByPhone(registerBody.getPhone());

        }

        // 4.获取登录token
        return R.ok(tokenService.createToken(loginUser));
    }

    @DeleteMapping("logout")
    public R<?> logout(HttpServletRequest request) {
        String token = SecurityUtils.getToken(request);
        if (StringUtils.isNotEmpty(token)) {
            String username = JwtUtils.getUserName(token);
            // 删除用户缓存记录
            AuthUtil.logoutByToken(token);
            // 记录用户退出日志
            loginService.logout(username);
        }
        return R.ok();
    }

    @PostMapping("refresh")
    public R<?> refresh(HttpServletRequest request) {
        LoginUser LoginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(LoginUser)) {
            // 刷新令牌有效期
            tokenService.refreshToken(LoginUser);
            return R.ok();
        }
        return R.ok();
    }

    @PostMapping("register")
    public R<?> register(@RequestBody @Validated({RegisterBody.register.class})RegisterBody registerBody) {
        // 1.发送邮件/校验短信
        if (registerBody.getUsername().matches("/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$/")){
            // 校验短信验证码(在gateway已校验)

        }else {
            // 发送邮件
            loginService.sendActiveCode(registerBody.getUsername());
        }

        // 2.用户注册
        loginService.register(registerBody);

        // 3.返回注册成功！提示用户激活邮箱后登录
        return R.ok(null,"注册成功！请查看邮箱激活账号后登录！");
    }

    @GetMapping("sendEmail")
    public AjaxResult sendActiveCode(@RequestParam @Email String email){
        return loginService.sendActiveCode(email);
    }

    // @GetMapping("active")
    // public AjaxResult sendActiveCode(@RequestParam @Email String email,@RequestParam String uuid){
    //     return loginService.activeEmail(email,uuid);
    // }

    @GetMapping("sms")
    public AjaxResult sendSms(@RequestParam String phone){
        AtomicReference<Boolean> flag = new AtomicReference<>(true);
        // 1. 获取所有SMS_*
        Collection<String> keys = redisService.keys(CacheConstants.SMS_CODE_KEY.concat("*"));
        keys.forEach(e ->{
            // 2.根据当前key获取phone
            Map<String,String> smsCache = redisService.getCacheObject(e);
            String smsPhone = smsCache.get("phone");
            if (phone.equals(smsPhone)){
                // 3.当过期时间 >=240s 时，说明用户在60秒内重复获取验证码，此时返回获取验证码过于频繁
                long expire = redisService.getExpire(e);
                if (expire >= 240){
                    flag.compareAndSet(Boolean.TRUE, Boolean.FALSE);
                }
            }
        });
        if (!flag.get()){
            return AjaxResult.error("获取验证码过于频繁");
        }

        Sms sms = new Sms();
        sms.setPhone(phone);

        // ********************************************
        // String uuid = IdUtils.fastSimpleUUID();
        // // 构造存储内容
        // Map<String, Object> voMap = new HashMap<>();
        // voMap.put("phone", sms.getPhone());
        // voMap.put("code", "1234");
        // // 存储到redis
        // String verifyKey = CacheConstants.SMS_CODE_KEY + uuid;
        // redisService.setCacheObject(verifyKey, voMap, CacheConstants.SMS_EXPIRATION, TimeUnit.MINUTES);
        // // 填充返回结果
        // voMap.remove("code");
        // voMap.put("uuid", uuid);
        // return AjaxResult.success(voMap);
        // ********************************************

        return sendMessageService.sendSMSCode(sms);
    }
}
